home *** CD-ROM | disk | FTP | other *** search
- _AN OBJECT-ORIENTED ASSEMBLY LANGUAGE MACRO LIBRARY_
- by Donald J. McSwain
-
-
- [LISTING ONE]
-
- Macro File: objects.mac
-
- COMMENT % ===============================================================
- Sets up stack, SI with object pointer, DX with message number, and calls
- sendMsg procedure.
- Passed: Obj - Name of receiving object; Msg - Message number
- =========================================================================%
- send MACRO Obj,Msg,ArgList
- pushArgs ArgList ;Push arguments onto stack
- IFIDN <Obj>,<Self> ;If object is Self
- mov si,Wptr[Self] ;Get object ptr from it
- ELSE
- IFDIF <Obj>,<si> ;If object ptr not in SI
- lea si,Obj ;Load SI with ptr to object
- ENDIF
- ENDIF
-
- IFDIF <Msg>,<dx> ;If msg number not in DX
- mov dx,Msg ;Put it in DX
- ENDIF
-
- call sendMsg ;Send message
- IFNB <ArgList> ;If arguments
- X = 0 ;Init stack depth counter
- IRP Arg,<ArgList> ;For every arg on stack
- X = X+2 ;Increment depth counter
- ENDM
- add sp,X ;Reset stack pointer
- ENDIF
- ENDM
-
- COMMENT % ===============================================================
- Pushes up to ten arguments onto the stack.
- =========================================================================%
- pushArgs MACRO A0,A1,A2,A3,A4,A5,A6,A7,A8,A9
- IFB <A0> ;If no more arguments
- EXITM ;Exit macro
- ENDIF
-
- IFIDN <A0>,<ax> ;If arg in AX
- push ax ;Push AX
- ELSE
- IFIDN <A0>,<bx> ;If arg in BX
- push bx ;Push BX
- ELSE
- IFIDN <A0>,<cx> ;If arg in CX
- push cx ;Push CX
- ELSE
- IFIDN <A0>,<dx> ;If arg in DX
- push dx ;Push DX
- ELSE
- mov bx,A0 ;Else move into BX
- push bx ;Push BX
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- pushArgs A1,A2,A3,A4,A5,A6,A7,A8,A9
- ENDM
-
- COMMENT % =============================================================
- Finds the specified message for specified object.
- Passed: Msg - Message number; Obj - Addr ptr to object structure
- Passes: si - Pointer to combined method pointer
- =========================================================================%
- findMsg MACRO Obj,Msg,Lbl
- LOCAL fdmg1,fdmg2
- IFDIF <Obj>,<si> ;If object ptr is not in SI
- mov si,Obj ;Put it there
- ENDIF
- mov di,Wptr[si].Instances
- ;Addr of msg tbl end
- mov si,Wptr[si].Messages
- ;Addr of msg tbl beginning
- fdmg1: lodsb ;Fetch msg number
- eq al,Msg,fdmg2 ;Exit if message is found
- add si,2 ;Else point to next message
- cmp si,di ;More messages?
- jb fdmg1 ;If so continue search
-
- IFNB <Lbl> ;If label provided
- jmp Lbl ;Jump to it upon failure
- ENDIF
- fdmg2:
- ENDM
-
- Source File: objects.asm
- PUBLIC sendMsg
- COMMENT % ===================================================================
- Sends the specified object the given message. This causes the execution of
- the combined message for the object.
- Passed: dx - Message number; si - Combined method ptr
- =============================================================================%
- sendMsg PROC NEAR
- findMsg si,dl,smg2 ;Search for message
- mov si,Wptr[si] ;Get method addr
- mov cx,Wptr[si] ;Get method count
- smg1: add si,2 ;Point to method
- pushData <cx,si> ;Save loop cnt, addr ptr
- call Wptr[si] ;Execute method
- popData <si,cx> ;Restore addr ptr, loop cnt
- loop smg1 ;Loop
- smg2: ret
- sendMsg ENDP
-
-
- [LISTING TWO]
-
-
- Include File: objects.inc
-
- COMMENT % ==================================================================
- Data structure used to hold pointers to an object's ancestors, messages, and
- instance variables.
- ===========================================================================%
- _Object STRUC
- Objects DW Nil
- Messages DW Nil
- Instances DW Nil
- _Object ENDS
-
- Macro File: objects.mac
-
- COMMENT % ===================================================================
- Defines an object.
- Passed: Obj - Object name; Objs - Ancestor list; Instances - Instance
- variable list; Messages - Message list
- =============================================================================%
- defObj MACRO Obj,Objs,Instances,Messages
- LOCAL ObjTbl,MsgTbl,InstTbl
-
- ObjTbl LABEL WORD
- objsDef Obj,<Objs>
-
- MsgTbl LABEL WORD
- msgsDef Obj,<Messages>
- InstTbl LABEL WORD
- instDef <Instances>
- ALIGN 2
- PUBLIC Obj
- Obj _Object <ObjTbl,MsgTbl,InstTbl>
- ENDM
-
- COMMENT % ===================================================================
- Defines objects.
- Passed: Obj - Object name; Objs - Ancestor list
- =============================================================================%
- objsDef MACRO Obj,Objs
- DW Obj
- IRP Obj,<Objs>
- DW Obj
- ENDM
- ENDM
-
- COMMENT % ====================================================================
- Defines messages.
- Passed: Obj - Object name; Messages - Message list
- =============================================================================%
- msgsDef MACRO Obj,Messages
- IRP Msg,<Messages>
- DB Msg ;Msg# identifies msg
- IFNDEF Obj&&Msg
- DW Nil ;Obj has no local methods
- ELSE
- DW Obj&&Msg ;Obj has local methods
- ENDIF
- ENDM
- ENDM
-
- COMMENT % ===================================================================
- Defines instances variables.
- Passed: Instances - Instance variable list
- =============================================================================%
- instDef MACRO Instances
- X = 0
- Y = 0
- IRP Inst,<Instances>
- defInst Inst,%X,%Y
- ENDM
- ENDM
-
- COMMENT % ====================================================================
- Defines an instance variable.
- Passed: Inst - Instance variable name; Cnt - Instance variable field number;
- Size - Size of instance variable
- =============================================================================%
- defInst MACRO Inst,Cnt,Size
- IFIDN <Cnt>,<0>
- X = X+1
- ELSE
- IFIDN <Cnt>,<1>
- X = X+1
- Y = Inst
- ELSE
- X = 0
- defVar Size,Inst
- ENDIF
- ENDIF
- ENDM
-
- COMMENT % ====================================================================
- Defines a data item.
- Passed: Size - Size of data in bytes; Value - Value of data item
- =============================================================================%
- defVar MACRO Size,Value
- IFIDN <Size>,<1>
- DB Value
- ELSE
- IFIDN <Size>,<2>
- DW Value
- ELSE
- IFIDN <Size>,<4>
- DD Value
- ELSE
- IFIDN <Size>,<8>
- DQ Value
- ELSE
- IFIDN <Size>,<10>
- DT Value
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDM
-
-
-
-
- [LISTING THREE]
-
- Include File: objects.inc
-
- COMMENT % ==================================================================
- Data structure used to hold pointers to a message's Before, Primary, and
- After methods.
- ===========================================================================%
- _Message STRUC
- Before DW Nil
- Primary DW Nil
- After DW Nil
- _Message ENDS
-
- Macro File: objects.mac
-
- COMMENT % ====================================================================
- Defines a message.
- Passed: Obj - Object name; Msg - Message name; Methods - Method list
- =============================================================================%
- defMsg MACRO Obj,Msg,Methods
- ALIGN 2
- Obj&Msg _Message <Methods>
- ENDM
-
-
-
-
- [LISTING FOUR]
-
- Macro File: objects.mac
-
- COMMENT % ====================================================================
- Sets us SI to point to object, and calls initObject procedure.
- =============================================================================%
- initObj MACRO Obj
- lea si,Obj ;Pass object ptr
- call initObject ;Find all ancestors
- ENDM
-
- Source File: objects.asm
-
- PUBLIC initObject
- COMMENT % ====================================================================
- Initializes an object by flattening its inheritance lattice to create
- combined methods for its messages.
- Passed: si - Addr ptr to object structure
- =============================================================================%
- initObject PROC NEAR
- lea di,Buffer ;Get buffer addr
- call findAncestors ;Find/Save all ancestors
- call evalMsgs ;Evaluate messages
- ret
- initObject ENDP
-
- COMMENT % ====================================================================
- Finds all of an object's ancestors and saves them for use by the message
- evaluator.
- Passed: bx - Addr ptr to message table (end of object table); di - Addr ptr
- to temporary object table; si - Addr ptr to object structure
- =============================================================================%
- findAncestors PROC NEAR
- pushData <bx,si> ;Save obj ptr
- mov bx,Wptr[si].Messages ;Get addr ptr to msg tbl
- mov si,Wptr[si].Objects ;Get addr of object tbl
- movsw ;Move obj ptr
- fas1: eq bx,si,fas2 ;Exit if end of tbl
- push si
- mov si,Wptr[si] ;Get next object
- call findAncestors ;Find others
- pop si
- add si,2
- jmp fas1 ;More in tbl - Loop
- fas2: mov Wptr[di],Nil ;Mark end of list
- popData <si,bx> ;Restore obj ptr
- ret
- findAncestors ENDP
-
- COMMENT % ====================================================================
- Creates combined methods for all of an object's messages.
- Passed: si - Addr ptr to object structure
- =============================================================================%
- evalMsgs PROC NEAR
- mov bx,Wptr[si].Messages ;Get addr of message tbl
- mov cx,Wptr[si].Instances ;Get addr of instance tbl
- ems1: mov dl,Bptr[bx] ;Get msg number
- xor dh,dh
- call combineMethods ;Combine methods
- add bx,3 ;Point to next tbl entry
- neq bx,cx,ems1 ;More in tbl? - loop
- ret
- evalMsgs ENDP
-
- COMMENT % ====================================================================
- Combines methods for all included objects.
- Passed: dx - Message number; si - Addr ptr to object structure
- =============================================================================%
- combineMethods PROC NEAR
- push bx
- mov ?Compiled,Nil ;Clear compiled flag
- mov bx,Wptr[CompileStart] ;Get start of combined mthd
- mov Wptr[CompilePtr],bx ;Init location ptr
- mov di,Nil ;Zero count word
- call saveMethodAddr ;Save value
- call saveBefores ;Save Before methods
- mov bx,Primary ;Select Primary method type
- lea di,Buffer ;Get addr of tmp object tbl
- mov di,Wptr[di] ;Get tbl entry
- call saveMethod ;Save method
- call saveAfters ;Save After methods
- null ?Compiled,cms1 ;Nothing compiled? - Exit
- call updatePtrs ;Update message, location ptrs
- cms1: pop bx
- ret
- combineMethods ENDP
-
- COMMENT % ====================================================================
- Updates the message and location pointers.
- Passed: dx - Message number; si - Addr ptr to object structure
- =============================================================================%
- updatePtrs PROC NEAR
- push si
- findMsg si,dl ;Find message
- mov di,Wptr[CompileStart] ;Get ptr to combined method
- mov Wptr[si],di ;Change message ptr
-
- mov bx,Wptr[CompilePtr] ;Get current compile location
- mov Wptr[CompileStart],bx ;Reset start of combined mthd
- pop si
- ret
- updatePtrs ENDP
-
- COMMENT % ====================================================================
- Save the Before method type for the specified object.
- Passed: dx - Message number
- =============================================================================%
- saveBefores PROC NEAR
- push si
- mov bx,Before ;Select Before method type
- lea si,Buffer ;Get addr of tmp object tbl
- mov di,Wptr[si] ;Get tbl entry
- sbs1: call saveMethod ;Save method
- add si,2 ;Point to next tbl entry
- mov di,Wptr[si] ;Get next tbl entry
- identity di,sbs1 ;More in table? - loop
- pop si
- ret
- saveBefores ENDP
-
- COMMENT % ===================================================================
- Save the After method type for the specified object.
- Passed: dx - Message number
- =============================================================================%
- saveAfters PROC NEAR
- pushData <cx,si>
- mov bx,After ;Select After method type
- lea si,Buffer ;Get addr of tmp object tbl
- mov cx,si ;Save addr of object tbl
- sas1: mov ax,Wptr[si] ;Get tbl entry
- null ax,sas2 ;Null? - End of tbl, exit
- add si,2 ;Point to next tbl entry
- jmp sas1 ;Loop
- sas2: sub si,2 ;Point to previous tbl entry
- mov di,Wptr[si] ;Get next tbl entry
- call saveMethod ;Save method
- neq si,cx,sas2
- popData <si,cx>
- ret
- saveAfters ENDP
-
- COMMENT % ====================================================================
- Save the specified method for specified object.
- Passed: bx-Method type; di-Addr ptr to object structure; dx-Message number
- =============================================================================%
- saveMethod PROC NEAR
- pushData <bx,di,si>
- findMsg di,dl,svm3 ;Find message
- mov di,Wptr[si] ;Get method tbl addr ptr
- null di,svm3 ;Exit if no local methods
- mov di,Wptr[di+bx] ;Get method addr ptr
- null di,svm3 ;Exit if no message
- mov bx,Wptr[CompileStart] ;Get start of combined mthd
- svm1: eq bx,Wptr[CompilePtr],svm2
- eq di,Wptr[bx],svm3 ;Exit if duplicate method
- add bx,2 ;Point to next addr
- jmp svm1 ;Check next addr
- svm2: call saveMethodAddr ;Save method addr
- svm3: popData <si,di,bx>
- ret
- saveMethod ENDP
-
- COMMENT % ====================================================================
- Save value at current compile location, and increments location pointer.
- Passed: di - Value to store
- =============================================================================%
- saveMethodAddr PROC NEAR
- mov ?Compiled,1 ;Set compiled flag
- mov bx,Wptr[CompilePtr] ;Get ptr to combined mthd end
- mov Wptr[bx],di ;Save value
- add bx,2 ;Point to next location
- mov Wptr[CompilePtr],bx ;Reset location ptr
- mov bx,Wptr[CompileStart] ;Get ptr mthd count
- mov di,Wptr[bx] ;Get mthd count
- inc di ;Increments mthd count
- mov Wptr[bx],di ;Save value
- ret
- saveMethodAddr ENDP
-
-
-
- [LISTING FIVE]
-
- Macro File: objects.mac
-
- COMMENT % ====================================================================
- Gets an object's instance variable.
- Passed: Dest- Destination register; Var - Instance variable name;
- Obj - Source object
- =============================================================================%
- getInst MACRO Dest,Var,Obj
- IFNB <Obj>
- IFIDN <Obj>,<Self>
- mov si,WORD PTR[Self]
- mov si,WORD PTR[si].Instances
- ELSE
- IFIDN <si>,<Obj>
- mov si,WORD PTR[si].Instances
- ELSE
- mov si,Obj&.Instances
- ENDIF
- ENDIF
- ENDIF
- mov Dest,[si+Var]
- ENDM
-
- COMMENT % ====================================================================
- Sets an object's instance variable.
- Passed: Var - Instance variable name; Source - Source register; Obj - Source
- object; Size - Size of data
- =============================================================================%
- setInst MACRO Var,Source,Obj,Size
- IFNB <Obj>
- IFIDN <Obj>,<Self>
- mov si,WORD PTR[Self]
- mov si,WORD PTR[si].Instances
- ELSE
- mov si,Obj&.Instances
- ENDIF
- ENDIF
- setInst_ Var,Source,Size
- ENDM
-
- COMMENT % ====================================================================
- Assembles move instruction based on source register.
- =============================================================================%
- setInst_ MACRO Var,Source,Size
- IFIDN <Source>,<al>
- mov BYTE PTR[si+Var],Source
- ELSE
- IFIDN <Source>,<ah>
- mov BYTE PTR[si+Var],Source
- ELSE
- IFIDN <Source>,<bl>
- mov BYTE PTR[si+Var],Source
- ELSE
- IFIDN <Source>,<bh>
- mov BYTE PTR[si+Var],Source
- ELSE
- IFIDN <Source>,<cl>
- mov BYTE PTR[si+Var],Source
- ELSE
- IFIDN <Source>,<ch>
- mov BYTE PTR[si+Var],Source
- ELSE
- IFIDN <Source>,<dl>
- mov BYTE PTR[si+Var],Source
- ELSE
- IFIDN <Source>,<dh>
- mov BYTE PTR[si+Var],Source
- ELSE
- IFIDN <Source>,<ax>
- mov WORD PTR[si+Var],Source
- ELSE
- IFIDN <Source>,<bx>
- mov WORD PTR[si+Var],Source
- ELSE
- IFIDN <Source>,<cx>
- mov WORD PTR[si+Var],Source
- ELSE
- IFIDN <Source>,<dx>
- mov WORD PTR[si+Var],Source
- ELSE
- IFIDN <Source>,<di>
- mov WORD PTR[si+Var],Source
- ELSE
- IFIDN <Source>,<si>
- mov WORD PTR[si+Var],Source
- ELSE
- IFIDN <Size>,<1>
- mov BYTE PTR[si+Var],Source
- ELSE
- IFIDN <Size>,<2>
- mov WORD PTR[si+Var],Source
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDM
-
-
-
-
-
- [LISTING SIX]
-
- Macro File: objects.mac
-
- COMMENT % ====================================================================
- Gets an object's instance variable, but object is pointed to by one of
- Self's instance variables.
- Passed: Dest- Destination register; Var - Instance variable name;
- Obj - Source object instance variable
- =============================================================================%
- getInst$ MACRO Dest,Var,Obj
- mov si,WORD PTR[Self]
- mov si,WORD PTR[si].Instances
- mov si,[si+Obj]
- mov si,WORD PTR[si].Instances
- mov Dest,[si+Var]
- ENDM
-
- COMMENT % ====================================================================
- Sets an object's instance variable, but object is pointed to by one of
- Self's instance variables.
- Passed: Var - Instance variable name; Source - Source register; Obj - Source
- object instance variable; Size - Size of data
- =============================================================================%
- setInst$ MACRO Var,Source,Obj,Size
- mov si,WORD PTR[Self]
- mov si,WORD PTR[si].Instances
- mov si,[si+Obj]
- mov si,WORD PTR[si].Instances
- setInst_ Var,Source,Size
- ENDM
-
-
-
-
- [Example 1]
-
- send Screen,Refresh,DoubleBdr ;Send Screen a Refresh msg
- send Self,Read ;Send Self a Read msg
- send Self,<WORD PTR[bx]> ;Send Self msg pointed to by
- ; BX register
-
-
- [Example 2]
-
- defObj Window,\ ;Define Window object
- <>,\ ;As a base object
- <>,\ ;With no inst vars
- <Refresh> ;Responds to Refresh msg
-
- defObj Border,\ ;Define Border object
- <>,\ ;As a base object
- <>,\ ;With no inst vars
- <Refresh> ;Responds to Refresh msg
-
- defObj Screen,\ ;Define Screen object
- <Window,Border>,\ ;As a derived object
- <Row1,1,1,\ ;With these inst vars
- Col1,1,0,\
- Row2,1,23,\
- Col2,1,79,\
- Color,1,34h,\
- BdrColor,1,30h,\
- MemSeg,2,Nil>,\
- <Refresh> ;Responds to Refresh msg
-
-
-
- [Example 3]
-
- defMsg Window,\ ;Define for Window object
- Refresh,\ ;The Refresh msg
- <clrWin,,> ;To clear window
-
- defMsg Border,\ ;Define for Border object
- Refresh,\ ;The Refresh msg
- <,,drawBdr> ;To draw border
-
- defMsg Screen,\ ;Define for Screen object
- Refresh,\ ;The Refresh msg
- <,drawBackDrop,drawLabel>
- ;To draw back drop and label
-
-
- [Example 4]
-
- defMsg Label,\ ;Define for Label object
- Refresh,\ ;The Refresh msg
- <,,drawLabel> ;To draw label
-
- defObj label,\ ;Define Label object
- <>,\ ;As a base object
- <>,\ ;With no inst vars
- <Refresh> ;Responds to Refresh msg
-
- defMsg Screen,\ ;Define for Screen object
- Refresh,\ ;The Refresh msg
- <,drawBackDrop,> ;To draw back drop
-
- defObj Screen,\ ;Define Screen object
- <Window,Border,Label>,\
- ;As a derived object
- <Row1,1,1,\ ;With these inst vars
- Col1,1,0,\
- Row2,1,23,\
- Col2,1,79,\
- Color,1,34h,\
- BdrColor,1,30h,\
- MemSeg,2,Nil>,\
- <Refresh> ;Responds to Refresh msg
-
-
-
-
- [Example 5]
-
- initObj Screen ;Combine methods for Screen
-
-
- [Example 6]
-
- getInst bl,Color,Screen ;Fetch Screen color
- setInst BdrColor,bl ;Copy it to BdrColor
- setInst Color,bl,Self ;And Self's color
-
-
-
- [Example 7]
-
- getInst$ bl,Color,Master ;Fetch color from object
- ; pointed to by Master
- setInst Color,bl,Self ;Copy it to Self's color
-